package com.ronghuanet.gift.userdetailservice;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.ronghuanet.gift.clients.UserClient;
import com.ronghuanet.gift.context.LoginUserContextInfo;
import com.ronghuanet.gift.domain.LoginUser;
import com.ronghuanet.gift.domain.Permission;
import com.ronghuanet.gift.exception.asserts.Assert;
import com.ronghuanet.gift.exception.code.StatusCode;
import com.ronghuanet.gift.mapper.LoginUserMapper;
import com.ronghuanet.gift.mapper.PermissionMapper;
import com.ronghuanet.gift.util.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Component
public class UserDetailServiceImpl implements UserDetailsService {

    @Autowired
    private LoginUserMapper userMapper;

    @Autowired
    private PermissionMapper permissionMapper;


    @Autowired
    private UserClient userClient;

    /**
     * 加载数据库中的认证的用户的信息：用户名，密码，用户的权限列表
     * @param username: 该方法把username传入进来，
        我们通过username查询用户的信息(密码，权限列表等)
        然后封装成 UserDetails进行返回 ，交给security 。
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //User是security内部的对象，UserDetails的实现类 ，
        //用来封装用户的基本信息（用户名，密码，权限列表）
        //public User(String username, String password, Collection<? extends GrantedAuthority> authorities)


        //@TODO 用户名+type才能确定一个用户，现在暂时约定用户名不重复
        List<LoginUser> loginUsers = userMapper.
                selectList(new EntityWrapper<LoginUser>()
                        .eq("username", username)
                        .or()
                        .eq("tel", username)
                        .or()
                        .eq("email", username)
                );

        Assert.assertListNotEmpty(loginUsers, StatusCode.CODE_400_CODE_USERNAME_OR_PASSWORD_ERROR);

        //模拟存储在数据库的用户的密码：123
        //String password = passwordEncoder.encode("123");
        LoginUser loginUser = loginUsers.get(0);

        LoginUserContextInfo contextInfo = new LoginUserContextInfo();
        contextInfo.setLoginUserId(loginUser.getId());
        contextInfo.setLoginUsername(loginUser.getUsername());

        Collection<GrantedAuthority> authorities = new ArrayList<>();
        if (loginUser.getType()==0)
        {
            //管理员 @TODO 自己做
            //Employee admin =null;
            contextInfo.setEmployeeId(1L);
            contextInfo.setEmpUsername("zs");

            //员工租户

            //查询管理员的权限
            List<Permission> permission = permissionMapper
                    .selectPermissionsByUserId(loginUser.getId());

            //用户的权限列表,暂时为空
            permission.forEach(e->{
                System.out.println("用户："+loginUser.getUsername()+" 加载权限："+e.getSn());
                authorities.add(new SimpleGrantedAuthority(e.getSn()));
            });

        }else{
            //查询用户
            AjaxResult ajaxResult = userClient.getByLoginId(loginUser.getId());
            if (ajaxResult.isSuccess()) {
                String userStr = (String) ajaxResult.getResultObj();
                com.ronghuanet.gift.domain.User user = JSONObject
                        .parseObject(userStr, com.ronghuanet.gift.domain.User.class);
                contextInfo.setUserId(user.getId());
                contextInfo.setUsername(user.getUsername());
            }

        }

        String password = loginUser.getPassword();
        User user = new User (JSONObject.toJSONString(contextInfo),
                password, authorities);
        return user;
    }
}